package com.engine4cloud.tdf.admin.service.impl;

import cn.hutool.core.io.IoUtil;
import com.amazonaws.services.s3.model.S3Object;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.engine4cloud.tdf.admin.api.dto.SysFileDownloadRequestDTO;
import com.engine4cloud.tdf.admin.api.dto.SysFileUploadRequestDTO;
import com.engine4cloud.tdf.admin.api.dto.SysFileUploadResultDTO;
import com.engine4cloud.tdf.admin.api.entity.SysFile;
import com.engine4cloud.tdf.admin.convert.SysFileConvert;
import com.engine4cloud.tdf.admin.mapper.SysFileMapper;
import com.engine4cloud.tdf.admin.service.SysFileService;
import com.engine4cloud.tdf.common.core.exception.BizException;
import com.engine4cloud.tdf.common.data.tenant.TenantContextHolder;
import com.engine4cloud.tdf.common.file.core.FileTemplate;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.InputStream;

/**
 * 文件管理
 *
 * @author wenjie
 * @date 2024-05-18 17:18:42
 */
@Slf4j
@Service
@AllArgsConstructor
public class SysFileServiceImpl extends ServiceImpl<SysFileMapper, SysFile> implements SysFileService {

	private final FileTemplate fileTemplate;

	/**
	 * 上传文件
	 *
	 * @param file 文件流
	 * @return SysFileUploadResultDTO
	 */
	@Override
	public SysFileUploadResultDTO uploadFile(MultipartFile file, SysFileUploadRequestDTO dto) {
		SysFileUploadResultDTO result = SysFileConvert.INSTANCE.convert(dto, file.getOriginalFilename());
		String dir = dto.getDir().getType() + (StringUtils.isEmpty(dto.getChildDir()) ? "" : ("/" + dto.getChildDir()));
		try (InputStream inputStream = file.getInputStream()) {
			fileTemplate.putObject(dto.getBucketName().getType(), dir, result.getFileName(), inputStream, file.getContentType());
		} catch (Exception e) {
			throw new BizException("上传失败", e);
		}
		return result;
	}

	/**
	 * 读取文件
	 *
	 * @param dto      文件名
	 * @param response response
	 */
	@Override
	public void getFile(SysFileDownloadRequestDTO dto, HttpServletResponse response) {
		TenantContextHolder.setTenantSkip();
		String dir = dto.getDir().getType() + (StringUtils.isEmpty(dto.getChildDir()) ? "" : ("/" + dto.getChildDir()));
		String fileName = dto.getFileName();
		try (S3Object s3Object = fileTemplate.getObject(dto.getBucketName().getType(), dir, fileName)) {
			response.setContentType("application/octet-stream; charset=UTF-8");
			// 设置文件名
			response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
			IoUtil.copy(s3Object.getObjectContent(), response.getOutputStream());
		} catch (Exception e) {
			throw new BizException("文件读取异常", e);
		}
	}

	@Override
	public byte[] getFile(SysFileDownloadRequestDTO dto) {
		TenantContextHolder.setTenantSkip();
		byte[] bytes = null;
		TenantContextHolder.setTenantSkip();
		String dir = dto.getDir().getType() + (StringUtils.isEmpty(dto.getChildDir()) ? "" : ("/" + dto.getChildDir()));
		//考虑到后期数据迁移复杂性，这里直接从minio获取，不走数据库
		try (S3Object s3Object = fileTemplate.getObject(dto.getBucketName().getType(), dir, dto.getFileName())) {
			bytes = IoUtil.readBytes(s3Object.getObjectContent());
		} catch (Exception e) {
			throw new BizException("文件读取异常", e);
		}
		return bytes;
	}
}
